package com.adamjwh.charroom.chatclient;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

//增加的包
import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.Thread;
import com.borland.jbcl.layout.*;



public class Frame1 extends JFrame {
  JPanel contentPane;
  JPanel jPanel1 = new JPanel();
  JPanel jPanel2 = new JPanel();
  XYLayout xYLayout1 = new XYLayout();
  JTextArea jTextArea1 = new JTextArea();
  XYLayout xYLayout2 = new XYLayout();
  JLabel jLabel1 = new JLabel();
  JLabel jLabel2 = new JLabel();
  JTextField jTextField1 = new JTextField();
  JButton jButton1 = new JButton();
  JButton jButton2 = new JButton();
  JTextField jTextField2 = new JTextField();
  JButton jButton3 = new JButton();
  JLabel jLabel3 = new JLabel();
  JTextField jTextField3 = new JTextField();
  XYLayout xYLayout3 = new XYLayout();
   java.awt.List list1 = new java.awt.List();
   ButtonGroup buttonGroup1 = new ButtonGroup();
     JRadioButton jRadioButton1 = new JRadioButton();
     JRadioButton jRadioButton2 = new JRadioButton();
     JScrollPane jScrollPane1 = new JScrollPane();
     JScrollPane jScrollPane2 = new JScrollPane();

//定义数据流和网络变量
  Socket socket=null;  //定义连接套接字
  PrintStream ps=null;  //定义打印流
  Listen listen=null;  //定义客户端线程
  int count=0;
  XYLayout xYLayout4 = new XYLayout();
  XYLayout xYLayout5 = new XYLayout();
  XYLayout xYLayout6 = new XYLayout();    //定义目前的连接用户数目
//Construct the frame
  public Frame1() {
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
  //Component initialization
  private void jbInit() throws Exception  {
    contentPane = (JPanel) this.getContentPane();
    contentPane.setLayout(xYLayout4);
    this.setSize(new Dimension(400, 328));
    this.setTitle("聊天客户端");
    jPanel2.setLayout(xYLayout5);
    jPanel1.setLayout(xYLayout6);
    jLabel1.setText("连接用户");
    jLabel2.setText("选择消息发送方式");
    jButton1.setText("发送");
    jButton1.addActionListener(new Frame1_jButton1_actionAdapter(this));
    jButton2.setText("退出");
    jButton2.addActionListener(new Frame1_jButton2_actionAdapter(this));
    jButton3.setText("连接");
    jButton3.addActionListener(new Frame1_jButton3_actionAdapter(this));
    jTextArea1.setText("");
    jTextField1.setText("");
    jTextField2.setEditable(false);
    jTextField2.setText("");
    jLabel3.setText("连接用户名");
    jTextField3.setText("");
    jRadioButton1.setEnabled(true);
    jRadioButton1.setSelected(true);
    jRadioButton1.setText("广播发送");
    jRadioButton2.setToolTipText("");
    jRadioButton2.setSelected(false);
    jRadioButton2.setText("选择发送");
    jPanel1.add(jScrollPane1,     new XYConstraints(5, 34, 134, 129));
    jPanel1.add(jLabel2, new XYConstraints(13, 175, 105, 28));
    jPanel1.add(jRadioButton1, new XYConstraints(17, 198, -1, -1));
    jPanel1.add(jRadioButton2,   new XYConstraints(17, 216, -1, -1));
    jPanel1.add(jLabel1, new XYConstraints(16, 4, 81, 20));
    jScrollPane1.getViewport().add(list1, null);
    contentPane.add(jTextField2,  new XYConstraints(3, 283, 371, 29));
    contentPane.add(jButton1, new XYConstraints(254, 245, -1, -1));
    contentPane.add(jTextField1,  new XYConstraints(23, 247, 215, 25));
    contentPane.add(jButton2, new XYConstraints(318, 246, -1, -1));
    contentPane.add(jPanel1, new XYConstraints(1, 0, 170, 246));
    jPanel2.add(jTextField3, new XYConstraints(71, 3, 80, -1));
    jPanel2.add(jButton3,  new XYConstraints(155, 0, 65, -1));
    jPanel2.add(jScrollPane2,   new XYConstraints(24, 31, 194, 162));
    jPanel2.add(jLabel3, new XYConstraints(0, 3, -1, -1));
    jScrollPane2.getViewport().add(jTextArea1, null);
    contentPane.add(jPanel2,    new XYConstraints(159, 1, 223, 209));
    buttonGroup1.add(jRadioButton2);
    buttonGroup1.add(jRadioButton1);
  }
  //Overridden so we can exit when window is closed
  protected void processWindowEvent(WindowEvent e) {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      disconnect();
      System.exit(0);
    }
  }

  public void disconnect(){
  //断开连接运行的方法
   if(socket!=null){
     try {
       ps.println("QUIT:"+listen.name);
       ps.flush();
       socket.close();
       count--;
     }
     catch(IOException e){
       jTextArea1.append("Error："+e);
     }
     //finally{}
   }
  }

 public class Listen extends  Thread{
            //   定义客户端线程用来监听服务器传来的信息
    //定义的数据成员
    String name=null;//用来存储客户端连接以后的name 信息
    DataInputStream dis=null;  //用来实现客户端接受服务器的数据的输入流
    PrintStream ps=null;//用来实现从客户端发送数据到服务器端的打印流
    Socket socket=null;//用来存储客户单的socket信息
    Frame1 parent=null;//用来存储当前运行的实例


    public Listen (Frame1 p,String n,Socket s){//Listen 类的构造器
      parent=p;
      name=n;
      socket=s;


      try{
        //实例化两个数据流
         dis=new DataInputStream(s.getInputStream());
         ps=new PrintStream(s.getOutputStream());
      }
      catch(IOException e){
        parent.jTextArea1.append("Error:  "+e+"\n");
        parent.disconnect();
      }
    }//结束类的构造器


    public void run(){
      //线程的运行方法
      String message=null;
      while(true){
        //无限循环用于监听信息
        try{
          message=dis.readLine();//读取服务器传来的信息
        }
        catch(IOException e){
          parent.jTextArea1.append("Error:  "+e+"\n");
          parent.disconnect();
        }
        if(message==null){
         //如果服务器传来的信息为空，则断开此次连接
         parent.listen=null;
         parent.socket=null;
         parent.list1.clear();
         return;
        }

        StringTokenizer str=new StringTokenizer(message,":");
        //用StringTokenizer类来实现读取分段字符
        String keyword=str.nextToken();
        //读取信息头来识别试何种信息
        if(keyword.equalsIgnoreCase("PEOPLE")){
          //如果读取的是PEOPLE，则表示是服务器发送的客户连接信息，
          //此时，需要刷新客户端的用户列表
          count=0;
          parent.list1.clear();
         while(str.hasMoreTokens()){
           String st = str.nextToken();
           //读取加入的用户名称
           parent.list1.addItem(st);

          //添加到用户列表中
          count++;//统计用户数目
        }
        jTextField2.setText("目前连接的用户数： "+String.valueOf(count));
        }

        else if(keyword.equalsIgnoreCase("MSG"))
        {
          //如果读取的是MSG，则表示是服务器发送的客户传来的聊天信息，
          //此时，需要刷新客户端的连天信息显示区，将聊天信息显示出来
          String broadcast=str.nextToken();//接受的信息类型，是单播还是广播
          String usr=str.nextToken();//信息发送的来源
          parent.jTextArea1.append(usr);
          parent.jTextArea1.append(str.nextToken("\0"));
          parent.jTextArea1.append("\n");
        }
          else if(keyword.equalsIgnoreCase("QUIT")){
            //如果关键字是QUIT，则判断是服务器的关闭信息，
            //用户需要用此信息来切断此次连接
            String who = str.nextToken();
            if (who.equalsIgnoreCase("SERVER")) {
              parent.jTextArea1.append("服务器关闭\n");
              try {
                parent.listen.stop();
                parent.listen = null;
                parent.socket.close();
                parent.socket = null;
              }
              catch (IOException e) {
                parent.jTextArea1.append("Error: " + e + "\n");
              }
              parent.list1.clear();
              return;
          }
          else{
              parent.jTextArea1.append(who+"已经离开\n");
          }
          }
          else if(keyword.equalsIgnoreCase("FAULTNAME"))
          {
            parent.jTextArea1.append("用户名错误\n");
          }
      }
    }//结束run方法
  }//结束内部的Listen类

 void jButton3_actionPerformed(ActionEvent e) {
 //用户点击“连接”按钮的处理方法
 if(socket==null){
  try{
    socket = new Socket(InetAddress.getLocalHost(), 4000);
    //使用端口8888实例化一个本地的套接字
    //socket.setSoTimeout(20000);
    //设置连接的最长时间为20秒
    if (socket != null) {
      ps = new PrintStream(socket.getOutputStream());
      //将ps指向socket的输出流
      StringBuffer info = new StringBuffer("PEOPLE:");
      //定义一个字符缓冲区存储发送信息
      //其中用PEOPLE为关键字，让服务器识别为连接信息
      //并将name以及IP信息用“：”分开，实现在服务器端通过用
      //StringTokenizer类来读取数据
      String userinfo = jTextField3.getText() + ":" +
          InetAddress.getLocalHost().toString();
      ps.println(info.append(userinfo));
      ps.flush();
      listen = new Listen(this, jTextField3.getText(), socket);
      listen.start();
      jTextArea1.append(jTextField3.getText() + "登录成功"+"\n");
      count++;
      jTextField2.setText("目前连接的用户数： " + String.valueOf(count));
    }
     else{
      jTextArea1.append(jTextField3.getText()+"登录失败");
     }
  }
   catch(IOException ee){
     jTextArea1.append(jTextField3.getText()+"登录失败");
     disconnect();
   }
  }//end of if
  }///结束“连接”方法

  void jButton1_actionPerformed(ActionEvent e) {
   //用户点击“发送”按钮的处理方法
   if(socket!=null){
     StringBuffer message=new StringBuffer("MSG:");
     //定义一个字符缓冲区存储发送信息
     //其中用MSG为关键字，让服务器识别为聊天信息
     try{
       String msg=new String(jTextField1.getText());
     }
     catch(Exception ex){}
    if(jRadioButton1.isSelected()){
    //查看选择的发送方式为“广播发送”还是“选择发送”
      message.append("BROAD:");
    }
    else{
      message.append(list1.getSelectedItem()+":");
    }
      message.append(listen.name+":");
     ps.println(message.append(jTextField1.getText()));
     jTextField1.setText("");
     //用打印流发送聊天信息
     ps.flush();
   }//结束if
  }//结束“发送”的处理方法

  void jButton2_actionPerformed(ActionEvent e) {
  //用户点击“退出”按钮的处理方法
  disconnect();
  System.exit(0);
  }



}//end of Frame1 class

class Frame1_jButton2_actionAdapter implements java.awt.event.ActionListener {
  Frame1 adaptee;

  Frame1_jButton2_actionAdapter(Frame1 adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
 adaptee.jButton2_actionPerformed(e);
  }
}

class Frame1_jButton1_actionAdapter implements java.awt.event.ActionListener {
  Frame1 adaptee;

  Frame1_jButton1_actionAdapter(Frame1 adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jButton1_actionPerformed(e);
  }
}

class Frame1_jButton3_actionAdapter implements java.awt.event.ActionListener {
  Frame1 adaptee;

  Frame1_jButton3_actionAdapter(Frame1 adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jButton3_actionPerformed(e);
  }
}
